package server.database;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import server.customers.CustomersTable;
import server.feedbacks.FeedbacksTable;
import server.orders.CustomersOrdersTable;
import server.orders.LineInOrderTable;
import server.orders.OrdersTable;
import server.resources.AreasTable;
import server.resources.CitiesTable;
import server.resources.CranesTable;
import server.resources.ProductCranesTable;
import server.resources.ProductsTable;
import server.resources.TrucksTable;
import server.users.UsersTable;
import services.ServiceException;

public class DatabaseService
{
	private static final Logger log = Logger.getLogger(DatabaseService.class);

	private static DatabaseService _instance;
	private DatabaseManager database = null;

	private Map<String, IDatabaseTable> m_mpTables;

	public static void initService() throws ServiceException
	{
		_instance = new DatabaseService();
		try
		{
			_instance.init();
		}
		catch (Exception e)
		{
			throw new ServiceException(e.getMessage());
		}
	}

	public static DatabaseService getInstance()
	{
		return _instance;
	}

	private void init() throws Exception
	{
		log.info("Initializing database service");

		database = new DatabaseManager();

		m_mpTables = new HashMap<String, IDatabaseTable>();

		m_mpTables.put(UsersTable.TABLE_NAME, new UsersTable());
		m_mpTables.put(FeedbacksTable.TABLE_NAME, new FeedbacksTable());
		m_mpTables.put(CustomersTable.TABLE_NAME, new CustomersTable());
		m_mpTables.put(TrucksTable.TABLE_NAME, new TrucksTable());
		m_mpTables.put(CranesTable.TABLE_NAME, new CranesTable());
		m_mpTables.put(ProductsTable.TABLE_NAME, new ProductsTable());
		m_mpTables.put(AreasTable.TABLE_NAME, new AreasTable());
		m_mpTables.put(CitiesTable.TABLE_NAME, new CitiesTable());
		m_mpTables.put(OrdersTable.TABLE_NAME, new OrdersTable());
		m_mpTables.put(CustomersOrdersTable.TABLE_NAME, new CustomersOrdersTable());
		m_mpTables.put(LineInOrderTable.TABLE_NAME, new LineInOrderTable());
		m_mpTables.put(ProductCranesTable.TABLE_NAME, new ProductCranesTable());

		for (IDatabaseTable table : m_mpTables.values())
		{
			try
			{
				table.initTable();
			}
			catch (Exception e)
			{
				log.error("init() - initializing table " + table.getTableName() + " has failed.");
				throw new Exception("init() - failed: " + e.getMessage());
			}
		}
	}

	public IDatabaseTable getTable(String sTableName)
	{
		return m_mpTables.get(sTableName);
	}

	public void closeDatabase()
	{
		database.closeConnection();
	}

	public List<Map<String, String>> query(String sQuery, List<DatabaseColumn> lstColumns) throws DatabaseException
	{
		return database.query(sQuery, lstColumns);
	}

	public void update(String sQuery) throws DatabaseException
	{
		database.update(sQuery);
	}

	public void execute(String sQuery) throws DatabaseException
	{
		database.execute(sQuery);
	}

	public int addAutoIncrement(String sQuery) throws DatabaseException
	{
		return database.addAutoIncrement(sQuery);
	}
}
